const BaseService = require('./base.service.js')
const ApiResponse = require('../common/api-response.js')
const UserController = require('./user.controller.js')

class WallpaperDictService extends BaseService {
  constructor({cloudObject}) {
	super({ cloudObject }) // 调用父类构造函数
	this.collectionName = 'iss-wallpaper-dict'
	this.userController = new UserController(cloudObject)
  }

  // 获取集合引用
  get collection() {
    return this.db.collection(this.collectionName)
  }

  /**
   * 分页查询字典列表
   * @param {Object} query - 查询参数
   * @returns {ApiResponse} 统一响应格式
   */
  async getList(query = {}) {
    try {
		// 对权限进行校验
		await this.userController.hasPermission('wdr','allin','permission')
		
      const whereConditions = {}
      
      if (query.type) {
        whereConditions.type = new RegExp(query.type, 'i')
      }
	  
	  if (query.name) {
	    whereConditions.name = new RegExp(query.name, 'i')
	  }
      
      if (query.status !== undefined) {
        whereConditions.status = query.status
      }

      const orderBy = query.orderBy || { sort: -1, create_time: -1 }
      const page = query.page || 1
      const pageSize = query.pageSize || 10

      const { total } = await this.collection.where(whereConditions).count()

      const data = await this.collection
        .where(whereConditions)
        .orderBy(orderBy)
        .skip((page - 1) * pageSize)
        .limit(pageSize)
        .get()

      return ApiResponse.success({
        total,
        list: data.data
      })
    } catch (e) {
      console.error('获取字典列表失败:', e)
      return ApiResponse.serverError('获取字典列表失败')
    }
  }

  /**
   * 根据id获取字典详情
   * @param {string} id - 字典ID
   * @returns {ApiResponse} 统一响应格式
   */
  async doc(id) {
    try {
      if (!id) {
        return ApiResponse.badRequest(ApiResponse.ErrorMessage.ID_REQUIRED)
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wdr','allin','permission')

      const response = await this.collection.doc(id).get()

      if (response.data && response.data.length === 1) {
        return ApiResponse.success(response.data[0])
      }
      return ApiResponse.notFound('字典记录未找到')
    } catch (e) {
      console.error('获取字典详情失败:', e)
      return ApiResponse.serverError('获取字典详情失败')
    }
  }

  /**
   * 根据类型获取字典选项
   * @param {string} type - 字典类型
   * @param {boolean} onlyEnabled - 是否只返回启用的选项
   * @returns {ApiResponse} 统一响应格式
   */
  async getOptionsByType(type, onlyEnabled = true) {
    try {
      if (!type) {
        return ApiResponse.badRequest('字典类型不能为空')
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wdr','allin','permission')

      const whereConditions = { type }
      if (onlyEnabled) {
        whereConditions.status = true
      }

      const response = await this.collection
        .where(whereConditions)
        .orderBy('sort', 'desc')
        .get()

      if (response.data && response.data.length > 0) {
        const dict = response.data[0]
        let options = dict.options || []
        
        if (onlyEnabled) {
          options = options.filter(opt => opt.status !== false)
        }
        
        // 按子项排序
        options.sort((a, b) => b.sort - a.sort)
        
        return ApiResponse.success(options)
      }
      
      return ApiResponse.success([])
    } catch (e) {
      console.error('获取字典选项失败:', e)
      return ApiResponse.serverError('获取字典选项失败')
    }
  }

  /**
   * 新增字典
   * @param {Object} data - 字典数据
   * @returns {ApiResponse} 统一响应格式
   */
  async add(data) {
    try {
      if (!data || !data.type) {
        return ApiResponse.badRequest('字典类型不能为空')
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wda','allin','permission')

      // 检查类型是否已存在
      const existRes = await this.collection.where({
        type: data.type
      }).count()
      
      if (existRes.total > 0) {
        return ApiResponse.badRequest('该字典类型已存在')
      }

      // 准备插入数据
      const insertData = {
        type: data.type,
		name: data.name,
        status: !!data.status,
        sort: data.sort || 0,
        options: Array.isArray(data.options) ? data.options : [],
        create_time: Date.now(),
        update_time: Date.now()
      }

      // 执行新增操作
      const result = await this.collection.add(insertData)

      return ApiResponse.success({
        id: result.id
      }, '字典创建成功')
    } catch (e) {
      console.error('创建字典失败:', e)
      return ApiResponse.serverError('创建字典失败')
    }
  }

  /**
   * 更新字典信息
   * @param {Object} data - 包含id和更新数据
   * @returns {ApiResponse} 统一响应格式
   */
  async update(data = {}) {
    try {
      if (!data || !data._id) {
        return ApiResponse.badRequest(ApiResponse.ErrorMessage.ID_REQUIRED)
      }

	  // 对权限进行校验
	  await this.userController.hasPermission('wde','allin','permission')
	  
      // 提取需要更新的数据
      const { _id, ...updateData } = data
      updateData.update_time = Date.now()

      // 执行更新
      const result = await this.collection.doc(_id).update(updateData)

      if (result.updated === 0) {
        return ApiResponse.notFound('字典记录未找到')
      }

      return ApiResponse.success({
        updated: result.updated
      }, '字典更新成功')
    } catch (e) {
      console.error('更新字典失败:', e)
      return ApiResponse.serverError('更新字典失败')
    }
  }

  /**
   * 批量删除字典
   * @param {Array<string>} ids - 要删除的ID数组
   * @returns {ApiResponse} 统一响应格式
   */
  async remove(ids) {
    try {
      if (!Array.isArray(ids) || ids.length === 0) {
        return ApiResponse.badRequest(ApiResponse.ErrorMessage.IDS_REQUIRED)
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wdd','allin','permission')

      const result = await this.collection.where({
        _id: this.dbCmd.in(ids)
      }).remove()

      if (result.deleted === 0) {
        return ApiResponse.notFound('字典记录未找到')
      }

      return ApiResponse.success({
        deleted: result.deleted
      }, '删除成功')
    } catch (e) {
      console.error('删除字典失败:', e)
      return ApiResponse.serverError('删除字典失败')
    }
  }

  /**
   * 切换字典状态
   * @param {string} id - 字典ID
   * @returns {ApiResponse} 统一响应格式
   */
  async toggleStatus(id) {
    try {
      if (!id) {
        return ApiResponse.badRequest(ApiResponse.ErrorMessage.ID_REQUIRED)
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wde','allin','permission')

      // 获取当前状态
      const doc = await this.collection.doc(id).get()
      if (!doc.data || !doc.data.length) {
        return ApiResponse.notFound('字典记录未找到')
      }

      // 取反状态
      const currentValue = doc.data[0].status
      const result = await this.collection.doc(id).update({
        status: !currentValue,
        update_time: Date.now()
      })

      if (result.updated === 0) {
        return ApiResponse.notFound('更新失败')
      }

      return ApiResponse.success({
        updated: result.updated
      }, '状态切换成功')
    } catch (e) {
      console.error('切换字典状态失败:', e)
      return ApiResponse.serverError('切换字典状态失败')
    }
  }

  /**
   * 添加字典选项
   * @param {string} id - 字典ID
   * @param {Object} option - 选项数据
   * @returns {ApiResponse} 统一响应格式
   */
  async addOption(id, option) {
    try {
      if (!id || !option || !option.code || !option.text) {
        return ApiResponse.badRequest('参数不完整')
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wda','allin','permission')

      // 检查code是否已存在
      const doc = await this.collection.doc(id).get()
      if (!doc.data || !doc.data.length) {
        return ApiResponse.notFound('字典记录未找到')
      }

      const dict = doc.data[0]
      if (dict.options && dict.options.some(opt => opt.code === option.code)) {
        return ApiResponse.badRequest('选项编码已存在')
      }

      // 准备选项数据
      const newOption = {
        code: option.code,
        text: option.text,
        description: option.description || '',
        status: option.status !== false,
        sort: option.sort || 0
      }

      // 执行更新
      const result = await this.collection.doc(id).update({
        options: this.dbCmd.push(newOption),
        update_time: Date.now()
      })

      if (result.updated === 0) {
        return ApiResponse.notFound('更新失败')
      }

      return ApiResponse.success({
        updated: result.updated
      }, '选项添加成功')
    } catch (e) {
      console.error('添加字典选项失败:', e)
      return ApiResponse.serverError('添加字典选项失败')
    }
  }

  /**
   * 更新字典选项
   * @param {string} id - 字典ID
   * @param {string} code - 选项编码
   * @param {Object} option - 选项数据
   * @returns {ApiResponse} 统一响应格式
   */
  async updateOption(id, code, option) {
    try {
      if (!id || !code || !option) {
        return ApiResponse.badRequest('参数不完整')
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wde','allin','permission')

      // 获取当前字典
      const doc = await this.collection.doc(id).get()
      if (!doc.data || !doc.data.length) {
        return ApiResponse.notFound('字典记录未找到')
      }

      const dict = doc.data[0]
      if (!dict.options || !dict.options.some(opt => opt.code === code)) {
        return ApiResponse.notFound('选项未找到')
      }

      // 更新选项
      const updatedOptions = dict.options.map(opt => {
        if (opt.code === code) {
          return {
            ...opt,
            text: option.text || opt.text,
            description: option.description || opt.description,
            status: option.status !== undefined ? option.status : opt.status,
            sort: option.sort !== undefined ? option.sort : opt.sort
          }
        }
        return opt
      })

      // 执行更新
      const result = await this.collection.doc(id).update({
        options: updatedOptions,
        update_time: Date.now()
      })

      if (result.updated === 0) {
        return ApiResponse.notFound('更新失败')
      }

      return ApiResponse.success({
        updated: result.updated
      }, '选项更新成功')
    } catch (e) {
      console.error('更新字典选项失败:', e)
      return ApiResponse.serverError('更新字典选项失败')
    }
  }

  /**
   * 删除字典选项
   * @param {string} id - 字典ID
   * @param {string|string[]} code - 选项编码或编码数组
   * @returns {ApiResponse} 统一响应格式
   */
  async removeOption(id, code) {
    try {
      if (!id || !code || (Array.isArray(code) && code.length === 0)) {
        return ApiResponse.badRequest('参数不完整');
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wdd','allin','permission')
  
      // 标准化code参数为数组形式
      const codesToRemove = Array.isArray(code) ? code : [code];
  
      // 获取当前字典
      const doc = await this.collection.doc(id).get();
      if (!doc.data || !doc.data.length) {
        return ApiResponse.notFound('字典记录未找到');
      }
  
      const dict = doc.data[0];
      if (!dict.options) {
        return ApiResponse.notFound('字典选项为空');
      }
  
      // 检查所有要删除的code是否存在
      const notFoundCodes = codesToRemove.filter(
        code => !dict.options.some(opt => opt.code === code)
      );
      
      if (notFoundCodes.length > 0) {
        return ApiResponse.notFound(
          `以下选项未找到: ${notFoundCodes.join(', ')}`
        );
      }
  
      // 过滤掉要删除的选项
      const updatedOptions = dict.options.filter(
        opt => !codesToRemove.includes(opt.code)
      );
  
      // 执行更新
      const result = await this.collection.doc(id).update({
        options: updatedOptions,
        update_time: Date.now()
      });
  
      if (result.updated === 0) {
        return ApiResponse.notFound('更新失败');
      }
  
      return ApiResponse.success({
        updated: result.updated,
        removedCodes: codesToRemove
      }, `成功删除 ${codesToRemove.length} 个选项`);
    } catch (e) {
      console.error('删除字典选项失败:', e);
      return ApiResponse.serverError('删除字典选项失败');
    }
  }

  /**
   * 切换选项状态
   * @param {string} id - 字典ID
   * @param {string} code - 选项编码
   * @returns {ApiResponse} 统一响应格式
   */
  async toggleOptionStatus(id, code) {
    try {
      if (!id || !code) {
        return ApiResponse.badRequest('参数不完整')
      }
	  
	  // 对权限进行校验
	  await this.userController.hasPermission('wdd','allin','permission')

      // 获取当前字典
      const doc = await this.collection.doc(id).get()
      if (!doc.data || !doc.data.length) {
        return ApiResponse.notFound('字典记录未找到')
      }

      const dict = doc.data[0]
      const optionIndex = dict.options ? dict.options.findIndex(opt => opt.code === code) : -1
      if (optionIndex === -1) {
        return ApiResponse.notFound('选项未找到')
      }

      // 切换选项状态
      const updatedOptions = [...dict.options]
      updatedOptions[optionIndex] = {
        ...updatedOptions[optionIndex],
        status: !updatedOptions[optionIndex].status
      }

      // 执行更新
      const result = await this.collection.doc(id).update({
        options: updatedOptions,
        update_time: Date.now()
      })

      if (result.updated === 0) {
        return ApiResponse.notFound('更新失败')
      }

      return ApiResponse.success({
        updated: result.updated
      }, '选项状态切换成功')
    } catch (e) {
      console.error('切换选项状态失败:', e)
      return ApiResponse.serverError('切换选项状态失败')
    }
  }
}

module.exports = WallpaperDictService